package org.springblade.modules.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import liquibase.pro.packaged.E;
import lombok.extern.slf4j.Slf4j;
import org.springblade.common.cache.DictCache;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.mp.base.BaseServiceImpl;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.modules.admin.dto.plan.score.PlanScoreSearchDTO;
import org.springblade.modules.admin.entity.*;
import org.springblade.modules.admin.enums.MaintainPlanContentEnum;
import org.springblade.modules.admin.enums.MaintainPlanContentStatusEnum;
import org.springblade.modules.admin.enums.StatusEnum;
import org.springblade.modules.admin.mapper.MaintainByScoreQuestionAppealMapper;
import org.springblade.modules.admin.mapper.MaintainCheckHistoryMapper;
import org.springblade.modules.admin.mapper.MaintainPlanScoreMapper;
import org.springblade.modules.admin.service.*;
import org.springblade.modules.admin.service.feishu.ILarkMaintenanceService;
import org.springblade.modules.admin.utils.WatermarkImgUtils;
import org.springblade.modules.admin.vo.*;
import org.springblade.modules.admin.vo.plan.PlanMaintainUserVO;
import org.springblade.modules.admin.vo.plan.store.*;
import org.springblade.modules.admin.vo.score.WxScoreFailureVo;
import org.springblade.modules.system.entity.Dict;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IDictService;
import org.springblade.modules.system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zcc
 * @version 1.0
 * @date 2024/1/15 13:47
 */
@Slf4j
@Service
public class MaintainPlanScoreServiceImpl extends BaseServiceImpl<MaintainPlanScoreMapper, MaintainPlanContent> implements MaintainPlanScoreService {

	@Autowired
	private ILarkMaintenanceService larkMaintenanceService;

	@Autowired
	private IMaintainPlanContentExtService maintainPlanContentExtService;


	@Autowired
	private IMaintainPlanContentUserService maintainPlanContentUserService;

	@Autowired
	private IPlanCheckHistoryScoreService planCheckHistoryScoreService;

	@Autowired
	private IPlanScoreDimensionItemService planScoreDimensionItemService;

	@Autowired
	private IMaintainPlanContentService maintainPlanContentService;

	@Autowired
	private ElevatorService elevatorService;

	@Autowired
	private IPlanScoreDimensionService planScoreDimensionService;

	@Autowired
	private IPlanHistoryScoreService planHistoryScoreService;

	@Autowired
	private IMaintainByScoreQuestionService maintainByScoreQuestionService;

	//状态1:表示工作项评分，2：表示任务记录评分
	private final static Integer[] status = {0, 1, 2};

	@Autowired
	private IUserService userService;

	@Autowired
	private IMaintainMalfunctionHistoryService maintainMalfunctionHistoryService;

	@Autowired
	@Lazy
	private IMaintainPlanAffairService maintainPlanAffairService;

	@Autowired
	@Lazy
	private IMaintainCheckHistoryService maintainCheckHistoryService;

	@Autowired
	private IDictService dictService;

	@Autowired
	private ByScoreQuestionAppealService appealService;

	@Autowired
	private IWxFaultCauseService wxFaultCauseService;

	@Autowired
	private IWxFaultTypeService wxFaultTypeService;

	@Override
	public ScoreByDetailVo getByPlanDetail(Long planId) {
		ScoreByDetailVo scoreByDetailVo = baseMapper.getPlanElevatorDetail(planId);
		List<PlanMaintainUserVO> maintainUserList = maintainPlanContentUserService.selectWorkUsers(planId);
		scoreByDetailVo.setMaintainPlanContentUserList(maintainUserList);
		MaintainPlanContentExt maintainPlanContentExt = maintainPlanContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId, planId));
		scoreByDetailVo.setMaintainPlanContentExt(maintainPlanContentExt);
		List<ScoreByTemplateVo> templateVos = baseMapper.getScoreByTemplates(planId, AuthUtil.getTenantId());
		scoreByDetailVo.setTemplateVos(templateVos);
		return scoreByDetailVo;
	}

	@Override
	public List<PlanTemplateVO> getPlanWorkItem(Long planId, Long templateId, Long checkHistoryId) {
		List<PlanTemplateVO> planCheckHistoryList = baseMapper.listPlanHistory(planId, templateId, AuthUtil.getTenantId(), checkHistoryId);
		planCheckHistoryList.forEach(e -> {
			e = disposePlanTemplateType(e, planId);
			e.setTemplateContentVOS(null);
		});

		for (PlanTemplateVO planTemplateVOS : planCheckHistoryList) {
			List<PlanTemplateTypeVO> templateTypeVOS = planTemplateVOS.getTemplateTypeVOS();
			List<PlanTemplateContentVO> templateContentVOS = new ArrayList<>(16);
			for (PlanTemplateTypeVO planTemplateTypeVO : templateTypeVOS) {
				getRecursionPlanTemplateVO(planTemplateTypeVO, templateContentVOS);
			}
			planTemplateVOS.setTemplateContentVOS(templateContentVOS);
		}
		return planCheckHistoryList;
	}


	private void getRecursionPlanTemplateVO(PlanTemplateTypeVO planTemplateTypeVO, List<PlanTemplateContentVO> templateContentVOS) {
		if (planTemplateTypeVO.getPlanTemplateContentVOS() != null) {
			templateContentVOS.addAll(planTemplateTypeVO.getPlanTemplateContentVOS());
		}
		if (planTemplateTypeVO.getChildren() != null && planTemplateTypeVO.getChildren().size() > 0) {
			List<PlanTemplateTypeVO> children = planTemplateTypeVO.getChildren();
			for (PlanTemplateTypeVO planTemplateTypeVO1 : children) {
				getRecursionPlanTemplateVO(planTemplateTypeVO1, templateContentVOS);
			}
		}
	}

	@Override
	public List<ScoreByCountVo> getScoreByCountDetail(String planIds) {
		//获取工作项的评分进度，如果没有任何工作项，获取任务追踪的进度,只返回项目信息
		List<Long> ids = new ArrayList<>(16);
		String[] split = planIds.split(",");
		for (String id : split) {
			ids.add(Convert.toLong(id));
		}
		List<Long> logPlanIds = new ArrayList<>(ids);
		List<ScoreByCountVo> scoreByCountDetail = baseMapper.getScoreByCountDetail(ids, AuthUtil.getTenantId());
		List<PlanCheckHistoryScore> list = planCheckHistoryScoreService.list(Wrappers.<PlanCheckHistoryScore>lambdaQuery().in(PlanCheckHistoryScore::getPlanId, ids).eq(PlanCheckHistoryScore::getStatus, 2));
		Map<Long, List<PlanCheckHistoryScore>> longListMap = list.stream().collect(Collectors.groupingBy(PlanCheckHistoryScore::getPlanId));
		for (ScoreByCountVo scoreByCountVo : scoreByCountDetail) {
			scoreByCountVo.setCheckCounts(scoreByCountVo.getCheckCounts() + 1);
			List<PlanCheckHistoryScore> planCheckHistoryScores = longListMap.get(scoreByCountVo.getPlanId());
			if (planCheckHistoryScores != null && planCheckHistoryScores.size() > 0) {
				scoreByCountVo.setScoreCounts(scoreByCountVo.getScoreCounts() + 1);
			}
		}
		//处理无工作项的任务进度
		List<Long> scorePlanIds = scoreByCountDetail.stream().map(ScoreByCountVo::getPlanId).collect(Collectors.toList());
		logPlanIds.removeAll(scorePlanIds);
		if (logPlanIds.size() > 0) {
			List<ScoreByCountVo> scoreByCountDetail2 = baseMapper.getScoreBuildingInfo(logPlanIds);
			scoreByCountDetail.addAll(scoreByCountDetail2);
		}

		//处理排序为了方便前端处理，按照ids顺序调整
		List<ScoreByCountVo> resultList = new ArrayList<>(16);
		Map<Long, List<ScoreByCountVo>> listMap = scoreByCountDetail.stream().collect(Collectors.groupingBy(ScoreByCountVo::getPlanId));
		for (Long id : ids) {
			resultList.add(listMap.get(id).get(0));
		}
		return resultList;
	}

	@Override
	public PlanCheckHistoryScore getScoreTemplate(Long checkHistoryId, Long scoreDimensionId, Boolean isUpdate) {
		PlanCheckHistoryScore scoreServiceOne = planCheckHistoryScoreService.getOne(Wrappers.<PlanCheckHistoryScore>lambdaQuery().eq(PlanCheckHistoryScore::getCheckHistoryId, checkHistoryId));
		if (scoreServiceOne != null) {
			MaintainPlanContentExt maintainPlanContentExt = maintainPlanContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId, scoreServiceOne.getPlanId()));
			Integer scoreStatus = 1;
			if (Convert.toInt(maintainPlanContentExt.getScoreStatus(), 0).equals(scoreStatus) && !isUpdate) {
				//如果已经提交-加载旧的评分项并且是查看的情况下
				Long dimensionId = scoreServiceOne.getScoreDimensionId();
				scoreDimensionId = dimensionId;
			}
		}
		//加载评分项
		List<PlanScoreDimensionItem> dimensionItems = planScoreDimensionItemService.list(Wrappers.<PlanScoreDimensionItem>lambdaQuery().eq(PlanScoreDimensionItem::getScoreDimensionId, scoreDimensionId).orderByAsc(PlanScoreDimensionItem::getScore));
		if (scoreServiceOne == null) {
			PlanScoreDimension planScoreDimension = planScoreDimensionService.getById(scoreDimensionId);
			if (planScoreDimension == null) {
				throw new ServiceException("找不到对应的评分模板,请检测参数");
			}
			scoreServiceOne = new PlanCheckHistoryScore();
			scoreServiceOne.setDimensionName(planScoreDimension.getDimensionName());
		}
		scoreServiceOne.setScoreTemplate(dimensionItems);
		//获取问题点记录
		MaintainByScoreQuestion maintainByScoreQuestion = maintainByScoreQuestionService.getOne(Wrappers.<MaintainByScoreQuestion>lambdaQuery().eq(MaintainByScoreQuestion::getCheckHistoryId, checkHistoryId));
		if (maintainByScoreQuestion != null) {
			User user = userService.getById(maintainByScoreQuestion.getCreateUser());
			if (user != null) {
				maintainByScoreQuestion.setCreateUserName(user.getRealName());
			}
		}
		scoreServiceOne.setMaintainByScoreQuestion(maintainByScoreQuestion);

		MaintainByScoreQuestionAppeal appeal = appealService.getOne(Wrappers.<MaintainByScoreQuestionAppeal>lambdaQuery().eq(MaintainByScoreQuestionAppeal::getPlanId, scoreServiceOne.getPlanId()));
		scoreServiceOne.setAppeal(appeal);

		return scoreServiceOne;
	}


	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean saveAndUpdateScore(PlanCheckHistoryScoreVO planCheckHistoryScoreVO) {
		PlanCheckHistoryScore planCheckHistoryScore = new PlanCheckHistoryScore();
		PlanCheckHistoryScore planCheckHistoryScore2 = planCheckHistoryScoreService.getOne(Wrappers.<PlanCheckHistoryScore>lambdaQuery().eq(PlanCheckHistoryScore::getCheckHistoryId, planCheckHistoryScoreVO.getCheckHistoryId()));
		if (planCheckHistoryScore2 != null) {
			planCheckHistoryScore = planCheckHistoryScore2;
			if (planCheckHistoryScoreVO.getDimensionItemId() == null) {
				planCheckHistoryScoreVO.setDimensionItemId(planCheckHistoryScore2.getDimensionItemId());
			}
		} else {
			planCheckHistoryScore.setPlanId(planCheckHistoryScoreVO.getPlanId());
			MaintainPlanContent maintainPlanContent = maintainPlanContentService.getById(planCheckHistoryScoreVO.getPlanId());
			planCheckHistoryScore.setElevatorId(maintainPlanContent.getElevatorId());
			Elevator elevator = elevatorService.getById(maintainPlanContent.getElevatorId());
			planCheckHistoryScore.setBuildingId(elevator.getBuildingId());
		}
		planCheckHistoryScore.setCheckHistoryId(planCheckHistoryScoreVO.getCheckHistoryId());
		planCheckHistoryScore.setScoreUserId(AuthUtil.getUserId());
		planCheckHistoryScore.setScoreUserName(AuthUtil.getNickName());
		planCheckHistoryScore.setScoreDesc(planCheckHistoryScoreVO.getScoreDesc());
		planCheckHistoryScore.setDimensionItemId(planCheckHistoryScoreVO.getDimensionItemId());
		if (planCheckHistoryScoreVO.getWxFaultIds() != null && planCheckHistoryScoreVO.getWxFaultIds().size() > 0) {
			planCheckHistoryScore.setWxFaultCauseIds(String.join(",", planCheckHistoryScoreVO.getWxFaultIds()));
		}
		if (planCheckHistoryScoreVO.getWxTypeIds() != null && planCheckHistoryScoreVO.getWxTypeIds().size() > 0) {
			planCheckHistoryScore.setWxFaultTypeIds(String.join(",", planCheckHistoryScoreVO.getWxTypeIds()));
		}
		planCheckHistoryScore.setWxFaultCauseDesc(planCheckHistoryScoreVO.getWxFaultCauseDesc());
		planCheckHistoryScore.setWxFaultTypeDesc(planCheckHistoryScoreVO.getWxFaultTypeDesc());

		//评分项信息
		PlanScoreDimensionItem scoreDimensionItem = planScoreDimensionItemService.getById(planCheckHistoryScoreVO.getDimensionItemId());
		planCheckHistoryScore.setScoreDimensionId(scoreDimensionItem.getScoreDimensionId());
		planCheckHistoryScore.setScoreLevel(scoreDimensionItem.getScoreLevel());
		planCheckHistoryScore.setScore(Convert.toBigDecimal(scoreDimensionItem.getScore()));
		planCheckHistoryScore.setCheckScore(Convert.toBigDecimal(scoreDimensionItem.getScore()));
		planCheckHistoryScore.setIsHasQuestion(scoreDimensionItem.getIsHasQuestion());
		PlanScoreDimension planScoreDimension = planScoreDimensionService.getById(scoreDimensionItem.getScoreDimensionId());
		if ("DK".equals(planScoreDimension.getPrefixCode())) {
			planCheckHistoryScore.setStatus(status[2]);
		} else {
			planCheckHistoryScore.setStatus(status[1]);
		}
		planCheckHistoryScore.setDimensionName(planScoreDimension.getDimensionName());

		if (Func.isNotEmpty(planCheckHistoryScore)) {
			planCheckHistoryScoreService.saveOrUpdate(planCheckHistoryScore);
		}

		//有效订单
		Integer scoreType = 1;
		MaintainPlanContentExt maintainPlanContentExt = maintainPlanContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId, planCheckHistoryScoreVO.getPlanId()));
		maintainPlanContentExt.setScoreType(planCheckHistoryScoreVO.getScoreType());
		if (planCheckHistoryScoreVO.getScoreType().equals(scoreType)) {
			List<PlanCheckHistoryScore> list = planCheckHistoryScoreService.list(Wrappers.<PlanCheckHistoryScore>lambdaQuery().eq(PlanCheckHistoryScore::getPlanId, planCheckHistoryScoreVO.getPlanId()));
			BigDecimal bigDecimal = list.stream().filter(o -> o.getCheckScore() != null).map(PlanCheckHistoryScore::getCheckScore).reduce(BigDecimal.ZERO, BigDecimal::add);

			List<PlanTemplateVO> planCheckHistoryList = baseMapper.listPlanHistory(maintainPlanContentExt.getPlanId(), null, AuthUtil.getTenantId(), null);
			List<List<PlanTemplateContentVO>> listList = planCheckHistoryList.stream().map(PlanTemplateVO::getTemplateContentVOS).collect(Collectors.toList());
			Integer checkHistorySize = 1;
			for (List<PlanTemplateContentVO> checkList : listList) {
				checkHistorySize = checkHistorySize + checkList.size();
			}
			//更新评分信息
			maintainPlanContentExt.setScoreDate(new Date());
			maintainPlanContentExt.setScoreUserId(planCheckHistoryScore.getScoreUserId());
			maintainPlanContentExt.setScoreUserName(planCheckHistoryScore.getScoreUserName());
			maintainPlanContentExt.setScoreRemark(planCheckHistoryScoreVO.getScoreRemark());
			BigDecimal divide = Convert.toBigDecimal(1).divide(Convert.toBigDecimal(checkHistorySize), 2, BigDecimal.ROUND_HALF_UP);
			maintainPlanContentExt.setScore(bigDecimal.multiply(divide));
		} else {
			maintainPlanContentExt.setScore(Convert.toBigDecimal(0));
		}
		maintainPlanContentExtService.updateById(maintainPlanContentExt);
		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean updatePlanScore(PlanCheckHistoryScoreVO planCheckHistoryScoreVO) {
		//表示已经评分
		Integer scoreStatus = 1;
		//表示有效订单
		Integer scoreType = 1;
		MaintainPlanContentExt maintainPlanContentExt = maintainPlanContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId, planCheckHistoryScoreVO.getPlanId()));
		//逻辑校验
		List<MaintainByScoreQuestion> scoreQuestionList = maintainByScoreQuestionService.list(Wrappers.<MaintainByScoreQuestion>lambdaQuery().eq(MaintainByScoreQuestion::getPlanId, maintainPlanContentExt.getPlanId()));
//		if (planCheckHistoryScoreVO.getScoreType().equals(scoreType)) {
//			Integer checkHistoryScoreSize = planCheckHistoryScoreService.list(Wrappers.<PlanCheckHistoryScore>lambdaQuery().eq(PlanCheckHistoryScore::getPlanId, planCheckHistoryScoreVO.getPlanId()).eq(PlanCheckHistoryScore::getIsHasQuestion, StatusEnum.ENABLE.getId())).size();
//			if (scoreQuestionList.size() != checkHistoryScoreSize) {
//				throw new ServiceException("有工作项的评分问题点未输入");
//			}
//		}
		maintainPlanContentExt.setScoreType(planCheckHistoryScoreVO.getScoreType());
		maintainPlanContentExt.setScoreDate(new Date());
		maintainPlanContentExt.setScoreUserId(AuthUtil.getUserId());
		maintainPlanContentExt.setScoreUserName(AuthUtil.getNickName());
		maintainPlanContentExt.setScoreRemark(planCheckHistoryScoreVO.getScoreRemark());
		maintainPlanContentExt.setScoreFutilityOtherDesc(planCheckHistoryScoreVO.getScoreFutilityOtherDesc());
		maintainPlanContentExt.setScoreFutilityDesc(planCheckHistoryScoreVO.getScoreFutilityDesc());
		maintainPlanContentExt.setScoreFutilityKey(planCheckHistoryScoreVO.getScoreFutilityKey());
		maintainPlanContentExt.setScoreStatus(scoreStatus);

		if (!planCheckHistoryScoreVO.getScoreType().equals(scoreType)) {
			maintainPlanContentExt.setScore(Convert.toBigDecimal(0));
			planCheckHistoryScoreService.remove(Wrappers.<PlanCheckHistoryScore>lambdaQuery().eq(PlanCheckHistoryScore::getPlanId, planCheckHistoryScoreVO.getPlanId()));
		}
		maintainPlanContentExtService.updateById(maintainPlanContentExt);
		PlanHistoryScore planHistoryScore = new PlanHistoryScore();
		BeanUtil.copyProperties(maintainPlanContentExt, planHistoryScore);
		planHistoryScore.setId(null);
		planHistoryScoreService.save(planHistoryScore);

		scoreQuestionList.stream().forEach(o -> o.setStatus(StatusEnum.ENABLE.getId()));
		maintainByScoreQuestionService.updateBatchById(scoreQuestionList);
		// 2024-06-12 新增无效工单评分时，发送飞书消息
		String tenantId = AuthUtil.getTenantId();
		if ("592800".equals(tenantId)) {
			larkMaintenanceService.sendPlanScoreLarkMessage(planCheckHistoryScoreVO.getPlanId());
		}

		//提交评分时,同时创建工单
		if (planCheckHistoryScoreVO.getMaintainPlanAffair() != null) {
			maintainPlanAffairService.add(planCheckHistoryScoreVO.getMaintainPlanAffair());
		}

		return true;
	}

	@Override
	@Transactional(rollbackFor = Exception.class)
	public Boolean delete(Long checkHistoryId) {

		PlanCheckHistoryScore scoreServiceOne = planCheckHistoryScoreService.getOne(Wrappers.<PlanCheckHistoryScore>lambdaQuery().eq(PlanCheckHistoryScore::getCheckHistoryId, checkHistoryId));
		if (scoreServiceOne == null) {
			return true;
		}
		MaintainPlanContentExt maintainPlanContentExt = maintainPlanContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId, scoreServiceOne.getPlanId()));
		planCheckHistoryScoreService.removeById(scoreServiceOne.getId());
		List<PlanCheckHistoryScore> list = planCheckHistoryScoreService.list(Wrappers.<PlanCheckHistoryScore>lambdaQuery().eq(PlanCheckHistoryScore::getPlanId, scoreServiceOne.getPlanId()));
		BigDecimal bigDecimal = list.stream().map(PlanCheckHistoryScore::getCheckScore).reduce(BigDecimal.ZERO, BigDecimal::add);
		//更新评分信息
		maintainPlanContentExt.setScoreDate(new Date());
		maintainPlanContentExt.setScore(bigDecimal);
		maintainPlanContentExtService.updateById(maintainPlanContentExt);
		return true;
	}

	@Override
	public ScoreCheckVo planScoreCheckV2(Long planId, Long templateId) {
		List<PlanTemplateVO> planCheckHistoryList = baseMapper.listPlanHistory(planId, templateId, AuthUtil.getTenantId(), null);
		planCheckHistoryList.forEach(e -> {
			e = disposePlanTemplateType(e, planId);
			e.setTemplateContentVOS(null);
		});

		for (PlanTemplateVO planTemplateVOS : planCheckHistoryList) {
			List<PlanTemplateTypeVO> templateTypeVOS = planTemplateVOS.getTemplateTypeVOS();
			List<PlanTemplateContentVO> templateContentVOS = new ArrayList<>(16);
			for (PlanTemplateTypeVO planTemplateTypeVO : templateTypeVOS) {
				getRecursionPlanTemplateVO(planTemplateTypeVO, templateContentVOS);
			}
			planTemplateVOS.setTemplateContentVOS(templateContentVOS);
		}
		List<PlanTemplateContentVO> templateContentVOS = planCheckHistoryList.get(0).getTemplateContentVOS();
		PlanTemplateContentVO planTemplateContentVO = templateContentVOS.get(templateContentVOS.size() - 1);
		ScoreCheckVo scoreCheckVo = new ScoreCheckVo();
		scoreCheckVo.setTemplateId(templateId);
		scoreCheckVo.setCheckHistoryId(planTemplateContentVO.getCheckHistoryId());
		scoreCheckVo.setCheckHistoryIndex(templateContentVOS.size() - 1);
		List<ScoreByTemplateVo> templateVos = baseMapper.getScoreByTemplates(planId, AuthUtil.getTenantId());
		for (int i = 0; i < templateVos.size(); i++) {
			if (templateVos.get(i).getTemplateId().equals(templateId)) {
				scoreCheckVo.setTemplateIndex(i);
				break;
			}
		}
		return scoreCheckVo;
	}


	@Override
	public ScoreCheckVo planScoreCheck(Long planId) {
		ScoreCheckVo scoreCheckVo = new ScoreCheckVo();
		List<PlanCheckHistoryScore> list = planCheckHistoryScoreService.list(Wrappers.<PlanCheckHistoryScore>lambdaQuery().eq(PlanCheckHistoryScore::getPlanId, planId));
		List<ScoreByTemplateVo> templateVos = baseMapper.getScoreByTemplates(planId, AuthUtil.getTenantId());
		List<PlanTemplateVO> planCheckHistoryList = maintainCheckHistoryService.getPlanWorkItem(planId, null, null);
		//如果评分项为空表示没有一个工作项评分
		if (planCheckHistoryList.size() > 0) {
			if (list.size() == 0) {
				PlanTemplateVO planTemplateVO = planCheckHistoryList.get(1);
				PlanTemplateContentVO planTemplateContentVO = planTemplateVO.getTemplateTypeVOS().get(0).getPlanTemplateContentVOS().get(0);
				scoreCheckVo.setTemplateId(planTemplateVO.getTemplateId());
				scoreCheckVo.setTemplateIndex(0);
				scoreCheckVo.setCheckHistoryId(planTemplateContentVO.getCheckHistoryId());
				scoreCheckVo.setCheckHistoryIndex(0);
				scoreCheckVo.setNature(planTemplateContentVO.getNature());
				return scoreCheckVo;
			} else {
				//有工作项评分，计算哪个工作项没有评分
				List<Long> checkHistoryIds = list.stream().map(PlanCheckHistoryScore::getCheckHistoryId).collect(Collectors.toList());
				for (int i = 0; i < templateVos.size(); i++) {
					ScoreByTemplateVo scoreByTemplateVo = templateVos.get(i);
					List<PlanTemplateVO> templateContentVOList = getPlanWorkItem(planId, scoreByTemplateVo.getTemplateId(), null);
					if (templateContentVOList.size() > 0) {
						List<PlanTemplateContentVO> templateContentVOS = templateContentVOList.get(0).getTemplateContentVOS();
						for (int j = 0; j < templateContentVOS.size(); j++) {
							PlanTemplateContentVO planTemplateContentVO = templateContentVOS.get(j);
							if (!checkHistoryIds.contains(planTemplateContentVO.getCheckHistoryId())) {
								scoreCheckVo.setTemplateId(scoreByTemplateVo.getTemplateId());
								scoreCheckVo.setTemplateIndex(i);
								scoreCheckVo.setCheckHistoryId(planTemplateContentVO.getCheckHistoryId());
								scoreCheckVo.setCheckHistoryIndex(j);
								scoreCheckVo.setNature(planTemplateContentVO.getNature());
								return scoreCheckVo;
							}
						}
					}
				}
			}
			//表示任务追踪评分
			Integer status = 2;
			List<PlanCheckHistoryScore> scoreList = list.stream().filter(o -> Convert.toInt(o.getStatus(), -1).equals(status)).collect(Collectors.toList());
			if (scoreList.size() == 0) {
				scoreCheckVo.setLogScore(true);
				PlanScoreDimension scoreDimension = planScoreDimensionService.getOne(Wrappers.<PlanScoreDimension>lambdaQuery().eq(PlanScoreDimension::getPrefixCode, "DK"));
				if (scoreDimension == null) {
					throw new ServiceException("当前租户没有设置打卡评分项");
				} else {
					scoreCheckVo.setNature(scoreDimension.getId());
				}
				return scoreCheckVo;
			}
		}
		scoreCheckVo.setIsSave(true);
		// 2024-05-17 新增 飞书异步逻辑
		String tenantId = AuthUtil.getTenantId();
		if ("592800".equals(tenantId)) {
			larkMaintenanceService.sendPlanScoreLarkMessage(planId);
		}
		return scoreCheckVo;
	}

	@Override
	public PlanCheckHistoryScore getScoreWxInfo(Long workId) {
		PlanCheckHistoryScore historyScore = planCheckHistoryScoreService.getOne(Wrappers.<PlanCheckHistoryScore>lambdaQuery().eq(PlanCheckHistoryScore::getCheckHistoryId, workId));
		if (historyScore == null) {
			historyScore = new PlanCheckHistoryScore();
		}
		List<MaintainMalfunctionHistory> malfunctionHistoryList = maintainMalfunctionHistoryService.list(Wrappers.<MaintainMalfunctionHistory>lambdaQuery().eq(MaintainMalfunctionHistory::getScoreWorkId, workId).orderByAsc(MaintainMalfunctionHistory::getCreateTime));
		historyScore.setMaintainMalfunctionHistorys(malfunctionHistoryList);
		return historyScore;
	}

	@Override
	public Boolean updatePlanScoreWx(PlanCheckHistoryScoreVO planCheckHistoryScoreVO) {
		MaintainPlanContentExt maintainPlanContentExt = maintainPlanContentExtService.getOne(Wrappers.<MaintainPlanContentExt>lambdaQuery().eq(MaintainPlanContentExt::getPlanId, planCheckHistoryScoreVO.getPlanId()));
		maintainPlanContentExt.setScoreType(planCheckHistoryScoreVO.getScoreType());
		maintainPlanContentExt.setScoreDate(new Date());
		maintainPlanContentExt.setScoreUserId(AuthUtil.getUserId());
		maintainPlanContentExt.setScoreUserName(AuthUtil.getNickName());
		maintainPlanContentExt.setScoreRemark(planCheckHistoryScoreVO.getScoreRemark());
		maintainPlanContentExt.setScoreFutilityOtherDesc(planCheckHistoryScoreVO.getScoreFutilityOtherDesc());
		maintainPlanContentExt.setScoreFutilityDesc(planCheckHistoryScoreVO.getScoreFutilityDesc());

		//表示已经评分
		Integer scoreStatus = 1;
		maintainPlanContentExt.setScoreStatus(scoreStatus);
		maintainPlanContentExtService.updateById(maintainPlanContentExt);
		PlanHistoryScore planHistoryScore = new PlanHistoryScore();
		BeanUtil.copyProperties(maintainPlanContentExt, planHistoryScore);
		planHistoryScore.setId(null);
		planHistoryScoreService.save(planHistoryScore);

		//更新问题点
		List<MaintainMalfunctionHistory> list = maintainMalfunctionHistoryService.list(Wrappers.<MaintainMalfunctionHistory>lambdaQuery().eq(MaintainMalfunctionHistory::getPlanId, planCheckHistoryScoreVO.getPlanId()).isNotNull(MaintainMalfunctionHistory::getScoreWorkId));
		if (list.size() > 0) {
			list.stream().forEach(o -> o.setStatus(StatusEnum.ENABLE.getId()));
			maintainMalfunctionHistoryService.updateBatchById(list);
		}
		return true;
	}

	@Override
	public List<ScoreByCountVo> getScoreByCountDetailWx(String planIds) {

		//获取维修的评分进度，如果没有任何工作项，获取任务追踪的进度,只返回项目信息
		List<Long> ids = new ArrayList<>(16);
		String[] split = planIds.split(",");
		for (String id : split) {
			ids.add(Convert.toLong(id));
		}
		List<Long> logPlanIds = new ArrayList<>(ids);
		List<ScoreByCountVo> scoreByCountDetail = baseMapper.getScoreByCountDetailWx(ids, AuthUtil.getTenantId());
		for (ScoreByCountVo scoreByCountVo : scoreByCountDetail) {
			scoreByCountVo.setCheckCounts(scoreByCountVo.getCheckCounts() + 1);
			List<PlanCheckHistoryScore> list = planCheckHistoryScoreService.list(Wrappers.<PlanCheckHistoryScore>lambdaQuery().eq(PlanCheckHistoryScore::getPlanId, scoreByCountVo.getPlanId()).eq(PlanCheckHistoryScore::getStatus, 2));
			if (list.size() > 0) {
				scoreByCountVo.setScoreCounts(scoreByCountVo.getScoreCounts() + 1);
			}
		}
		//处理无工作项的任务进度
		List<Long> scorePlanIds = scoreByCountDetail.stream().map(ScoreByCountVo::getPlanId).collect(Collectors.toList());
		logPlanIds.removeAll(scorePlanIds);
		if (logPlanIds.size() > 0) {
			List<ScoreByCountVo> scoreByCountDetail2 = baseMapper.getScoreBuildingInfo(logPlanIds);
			scoreByCountDetail.addAll(scoreByCountDetail2);
		}

		//处理排序为了方便前端处理，按照ids顺序调整
		List<ScoreByCountVo> resultList = new ArrayList<>(16);
		Map<Long, List<ScoreByCountVo>> listMap = scoreByCountDetail.stream().collect(Collectors.groupingBy(ScoreByCountVo::getPlanId));
		for (Long id : ids) {
			resultList.add(listMap.get(id).get(0));
		}
		return resultList;
	}


	@Override
	public List<WxByPlanHistoryVo> getWxByPlanHistoryList(PlanScoreSearchDTO planScoreSearchDTO) {

		if (planScoreSearchDTO.getTypeStatus() == MaintainPlanContentEnum.MAINTAIN_WX.getId()) {
			List<WxByPlanHistoryVo> wxByPlanHistoryVos = baseMapper.getWxPlanHistoryList(planScoreSearchDTO);
			if (wxByPlanHistoryVos.size() > 0) {
				List<WxByPlanHistoryVo> historyVos = wxByPlanHistoryVos.stream().filter(o -> o.getPlanId().equals(planScoreSearchDTO.getPlanId())).collect(Collectors.toList());
				if (historyVos != null && historyVos.size() > 0) {
					wxByPlanHistoryVos.removeAll(historyVos);
				}
			}
			for (WxByPlanHistoryVo wxByPlanHistoryVo : wxByPlanHistoryVos) {
				// 封装故障现象信息
				if (StringUtil.isNotBlank(wxByPlanHistoryVo.getProblemItem())) {
					List<String> problemKeys = Func.toStrList(wxByPlanHistoryVo.getProblemItem());
					List<String> problemNames = new ArrayList<>();
					for (String problemKey : problemKeys) {
						String problemName = DictCache.getValue("fault_problem", problemKey);
						problemNames.add(problemName);
					}
					wxByPlanHistoryVo.setPlanDesc(String.join(",", problemNames));
				}
			}
			return wxByPlanHistoryVos;
		} else {
			List<WxByPlanHistoryVo> byPlanHistoryList = baseMapper.getByPlanHistoryList(planScoreSearchDTO);
			if (byPlanHistoryList.size() > 0) {
				List<WxByPlanHistoryVo> historyVos = byPlanHistoryList.stream().filter(o -> o.getPlanId().equals(planScoreSearchDTO.getPlanId())).collect(Collectors.toList());
				if (Func.isNotEmpty(historyVos)) {
					byPlanHistoryList.removeAll(historyVos);
				}
				if (planScoreSearchDTO.getTemplateContentId() != null) {
					return byPlanHistoryList;
				}
				List<Long> planIds = byPlanHistoryList.stream().map(WxByPlanHistoryVo::getPlanId).distinct().collect(Collectors.toList());
				if (Func.isEmpty(planIds)) {
					return byPlanHistoryList;
				}
				List<MaintainCheckHistoryVO> checkHistories = baseMapper.selectByHistoryImgList(planIds, planScoreSearchDTO.getTemplateContentId());
				if (Func.isNotEmpty(checkHistories)) {
					List<Long> resultPlanIds = checkHistories.stream().filter(e -> {
						List<String> imgList = new ArrayList<>();
						if (Func.isNotEmpty(e.getRecordData())) {
							imgList.addAll(WatermarkImgUtils.findImgVideoUrl(e.getRecordData().toString()));
						}
						if (Func.isNotEmpty(e.getRecordVOS())) {
							List<MaintainCheckRecordVO> recordVOS = e.getRecordVOS().stream().sorted(Comparator.comparing(MaintainCheckRecordVO::getUpdateTime).reversed()).collect(Collectors.toList());
							MaintainCheckRecordVO recordVO = recordVOS.get(0);
							if (Func.isNotEmpty(recordVO.getRecordDataValue())) {
								imgList.addAll(WatermarkImgUtils.findImgVideoUrl(recordVO.getRecordDataValue().toString()));
							}
						}
						if (Func.isNotEmpty(imgList)) {
							return Boolean.TRUE;
						}
						return Boolean.FALSE;
					}).map(MaintainCheckHistoryVO::getPlanId).collect(Collectors.toList());
					if (Func.isNotEmpty(resultPlanIds)) {
						return byPlanHistoryList.stream().filter(e -> resultPlanIds.contains(e.getPlanId())).collect(Collectors.toList());
					}
				}
			}
			return new ArrayList<>();
		}

	}

	@Override
	public List<WxScoreFailureVo> getWxScoreFailureList(Long planId) {

		List<WxScoreFailureVo> list = baseMapper.getWxScoreFailureList(planId);
		List<WxFaultCause> causeList = wxFaultCauseService.list();
		List<WxFaultType> typeList = wxFaultTypeService.list();
		Map<Long, List<WxFaultType>> typeListMap = typeList.stream().collect(Collectors.groupingBy(WxFaultType::getId));
		Map<Long, List<WxFaultCause>> causeListMap = causeList.stream().collect(Collectors.groupingBy(WxFaultCause::getId));
		for (WxScoreFailureVo wxScoreFailureVo : list) {
			List<WxFaultCauseVO> wxFaultCauseVOS = new ArrayList<>(16);
			if (StrUtil.isNotEmpty(wxScoreFailureVo.getWxFaultCauseIds())) {
				String[] split = wxScoreFailureVo.getWxFaultCauseIds().split(",");
				for (String id : split) {
					WxFaultCause wxFaultCause = causeListMap.get(Convert.toLong(id)).get(0);
					WxFaultCauseVO wxFaultCauseVO = new WxFaultCauseVO();
					wxFaultCauseVO.setId(wxFaultCause.getId().toString());
					if (wxFaultCause.getFaultName().equals("其它") || wxFaultCause.getFaultName().equals("其他")) {
						wxFaultCauseVO.setOtherDesc(wxScoreFailureVo.getWxFaultCauseDesc());
					}
					wxFaultCauseVO.setName(wxFaultCause.getFaultName());
					wxFaultCauseVOS.add(wxFaultCauseVO);
				}
			}
			wxScoreFailureVo.setWxFaultCauseVOS(wxFaultCauseVOS);

			List<WxFaultTypeVO> wxFaultTypeVOS = new ArrayList<>(16);
			if (StrUtil.isNotEmpty(wxScoreFailureVo.getWxFaultTypeIds())) {
				String[] split = wxScoreFailureVo.getWxFaultTypeIds().split(",");
				for (String id : split) {
					WxFaultType wxFaultType = typeListMap.get(Convert.toLong(id)).get(0);
					WxFaultTypeVO wxFaultTypeVO = new WxFaultTypeVO();
					wxFaultTypeVO.setId(wxFaultType.getId().toString());
					wxFaultTypeVO.setName(wxFaultType.getName());
					if (wxFaultType.getName().equals("其它") || wxFaultType.getName().equals("其他")) {
						wxFaultTypeVO.setOtherDesc(wxScoreFailureVo.getWxFaultTypeDesc());
					}
					wxFaultTypeVOS.add(wxFaultTypeVO);
				}
			}
			wxScoreFailureVo.setWxFaultTypeVOS(wxFaultTypeVOS);
		}
		return list;
	}


	/**
	 * 封装模板分类及对应工作项
	 *
	 * @param planTemplateVO
	 * @return
	 */
	private PlanTemplateVO disposePlanTemplateType(PlanTemplateVO planTemplateVO, Long planId) {
		List<PlanTemplateContentVO> templateContentVOS = planTemplateVO.getTemplateContentVOS();
		List<PlanTemplateTypeVO> templateTypeVOS = getTypeZeroList(templateContentVOS);
		for (PlanTemplateContentVO t : templateContentVOS) {
			// 封装模板分类Tree
			List<String> tltIds = Func.toStrList(t.getTltIds());
			List<String> tltIdName = Func.toStrList("&&", t.getTltNames());
			if (tltIds.size() > 1) {
				for (int i = 1; i < tltIds.size(); i++) {
					templateTypeVOS = changeHistory(templateTypeVOS, Long.valueOf(tltIds.get(i)), tltIdName.get(i), Long.valueOf(tltIds.get(i - 1)));
				}
			}
		}
		// 封装对应工作项
		templateTypeVOS = changeHistoryContent(templateTypeVOS, templateContentVOS);
		templateTypeVOS.forEach(e -> {
			e = doCount(e, new HashMap<>());
		});
		planTemplateVO.setTemplateTypeVOS(templateTypeVOS);
		return planTemplateVO;
	}


	/**
	 * 封装任务历史数据分类Tree根节点
	 *
	 * @param templateContentVOS
	 * @return
	 */
	private List<PlanTemplateTypeVO> getTypeZeroList(List<PlanTemplateContentVO> templateContentVOS) {
		List<PlanTemplateTypeVO> planTemplateTypeVOS = templateContentVOS.stream().map(e -> {
			List<String> tltIds = Func.toStrList(e.getTltIds());
			List<String> tltIdName = Func.toStrList("&&", e.getTltNames());
			PlanTemplateTypeVO planTemplateTypeVO = new PlanTemplateTypeVO();
			planTemplateTypeVO.setTltId(Long.valueOf(tltIds.get(0)));
			planTemplateTypeVO.setTltName(tltIdName.get(0));
			planTemplateTypeVO.setTltParentId(0L);
			return planTemplateTypeVO;
		}).collect(Collectors.toList());
		planTemplateTypeVOS = planTemplateTypeVOS.stream().collect(Collectors.collectingAndThen(
			Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(e -> e.getTltId() + ";" + e.getTltName()))), ArrayList::new
		));
		return planTemplateTypeVOS;
	}

	/**
	 * 封装历史对应工作项分类数据
	 *
	 * @param planTemplateTypeVOS
	 * @param tltId
	 * @return
	 */
	private List<PlanTemplateTypeVO> changeHistory(List<PlanTemplateTypeVO> planTemplateTypeVOS, Long tltId, String tltName, Long parentId) {
		planTemplateTypeVOS.forEach(e -> {
			if (e.getTltId().equals(parentId)) {
				List<PlanTemplateTypeVO> children = e.getChildren();
				if (ObjectUtil.isEmpty(children)) {
					children = new ArrayList<>();
				}
				PlanTemplateTypeVO planTemplateTypeVO = new PlanTemplateTypeVO();
				planTemplateTypeVO.setTltId(tltId);
				planTemplateTypeVO.setTltName(tltName);
				planTemplateTypeVO.setTltParentId(parentId);
				children.add(planTemplateTypeVO);
				children = children.stream().collect(Collectors.collectingAndThen(
					Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(j -> j.getTltId() + ";" + j.getTltName()))), ArrayList::new
				));
				e.setChildren(children);
			} else {
				if (ObjectUtil.isNotEmpty(e.getChildren())) {
					changeHistory(e.getChildren(), tltId, tltName, parentId);
				}
			}
		});
		return planTemplateTypeVOS;
	}

	/**
	 * 封装历史记录对应工作项
	 *
	 * @param templateTypeVOS 分类tree集合
	 * @return
	 */
	private List<PlanTemplateTypeVO> changeHistoryContent(List<PlanTemplateTypeVO> templateTypeVOS, List<PlanTemplateContentVO> templateContentVOS) {
		templateTypeVOS.forEach(e -> {
			if (ObjectUtil.isEmpty(e.getChildren())) {
				templateContentVOS.forEach(j -> {
					List<String> tltIds = Func.toStrList(j.getTltIds());
					if (e.getTltId().equals(Long.valueOf(tltIds.get(tltIds.size() - 1)))) {
						List<PlanTemplateContentVO> planTemplateContentVOS = e.getPlanTemplateContentVOS();
						if (ObjectUtil.isEmpty(planTemplateContentVOS)) {
							planTemplateContentVOS = new ArrayList<>();
						}
						planTemplateContentVOS.add(j);
						e.setPlanTemplateContentVOS(planTemplateContentVOS);
					}
				});
			} else {
				changeHistoryContent(e.getChildren(), templateContentVOS);
			}
		});
		return templateTypeVOS;
	}

	/**
	 * 树形结构展示的某个节点的统计数值=所有子节点工作项数量总和
	 *
	 * @param root
	 * @param result
	 * @return
	 */
	public static PlanTemplateTypeVO doCount(PlanTemplateTypeVO root, Map<String, Object> result) {
		int count = 0;
		List<PlanTemplateTypeVO> list = root.getChildren();
		if (ObjectUtil.isEmpty(list)) {
			count = root.getPlanTemplateContentVOS().size();
			root.setWorkItemCount(count);
			return root;
		}

		for (PlanTemplateTypeVO child : list) {
			//统计子节点的孩子总数
			int cur_cnt = doCount(child, result).getWorkItemCount();
			result.put(String.valueOf(child.getTltId()), cur_cnt);
			count += cur_cnt;
			root.setWorkItemCount(count);
		}

		//返回前记录当前节点的统计个数
		result.put(String.valueOf(root.getTltId()), count);
		return root;
	}
}
